import { useRef, useEffect } from "react";
import type { BasicColumn, BasicTableProps, FetchParams, TableActionType } from "../types/table";
import type { FormActionType } from "@/components/Form";
// import { getDynamicProps } from "@/utils";
import { isProdMode } from "@/utils/env";
import type { Key } from "antd/lib/table/interface";
import { PaginationProps } from "../types/pagination";

type Props = Partial<BasicTableProps>;

type UseTableMethod = TableActionType & {
	getForm: () => FormActionType;
};

export function useTable(tableProps?: Props): [
	(instance: TableActionType, formInstance: UseTableMethod) => void,
	TableActionType & {
		getForm: () => FormActionType;
	}
] {
	const tableRef = useRef<Nullable<TableActionType>>(null);
	const loadedRef = useRef<Nullable<boolean>>(false);
	const formRef = useRef<Nullable<UseTableMethod>>(null);

	// let stopWatch: Function;

	useEffect(() => {
		tableProps && tableRef.current && tableRef.current.setProps(tableProps);
	}, [tableProps]);

	useEffect(() => {
		return () => {
			// clean function
			tableRef.current = null;
			loadedRef.current = null;
		};
	}, []);

	function register(instance: TableActionType, formInstance: UseTableMethod) {
		if (loadedRef.current && isProdMode() && instance === tableRef.current) return;

		tableRef.current = instance;
		formRef.current = formInstance;
		tableProps && instance.setProps(tableProps);
		loadedRef.current = true;
	}

	function getTableInstance(): TableActionType {
		const table = tableRef.current;
		if (!table) {
			console.error(
				"The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!"
			);
		}
		return table as TableActionType;
	}

	const methods: TableActionType & {
		getForm: () => FormActionType;
	} = {
		reload: (opt?: FetchParams) => {
			return getTableInstance()?.reload(opt);
		},
		setProps: (props: Partial<BasicTableProps>) => {
			getTableInstance()?.setProps(props);
		},
		redoHeight: () => {
			getTableInstance()?.redoHeight();
		},
		setSelectedRows: (rows: Recordable[]) => {
			return getTableInstance()?.setSelectedRows(rows);
		},
		setLoading: (loading: boolean) => {
			getTableInstance()?.setLoading(loading);
		},
		getDataSource: () => {
			return getTableInstance()?.getDataSource();
		},
		getRawDataSource: () => {
			return getTableInstance()?.getRawDataSource();
		},
		getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => {
			const columns = getTableInstance()?.getColumns({ ignoreIndex }) || [];
			return columns;
		},
		setColumns: (columns: BasicColumn[] | string[]) => {
			getTableInstance()?.setColumns(columns);
		},
		setTableData: (values: any[]) => {
			return getTableInstance()?.setTableData(values);
		},
		setPagination: (info: Partial<PaginationProps>) => {
			return getTableInstance()?.setPagination(info);
		},
		deleteSelectRowByKey: (key: string) => {
			getTableInstance()?.deleteSelectRowByKey(key);
		},
		getSelectRowKeys: () => {
			return getTableInstance()?.getSelectRowKeys();
		},
		getSelectRows: () => {
			return getTableInstance()?.getSelectRows();
		},
		clearSelectedRowKeys: () => {
			getTableInstance()?.clearSelectedRowKeys();
		},
		setSelectedRowKeys: (keys: (string | number)[]) => {
			getTableInstance()?.setSelectedRowKeys(keys);
		},
		getPaginationRef: () => {
			return getTableInstance()?.getPaginationRef();
		},
		getSize: () => {
			return getTableInstance()?.getSize();
		},
		updateTableData: (index: number, key: string, value: any) => {
			return getTableInstance()?.updateTableData(index, key, value);
		},
		deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => {
			return getTableInstance()?.deleteTableDataRecord(rowKey);
		},
		insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => {
			return getTableInstance()?.insertTableDataRecord(record, index);
		},
		updateTableDataRecord: (rowKey: string | number, record: Recordable) => {
			return getTableInstance()?.updateTableDataRecord(rowKey, record);
		},
		getRowSelection: () => {
			return getTableInstance()?.getRowSelection();
		},
		getCacheColumns: () => {
			return getTableInstance()?.getCacheColumns();
		},
		updateColumn: (column: BasicColumn | BasicColumn[]) => {
			return getTableInstance()?.updateColumn(column);
		},
		getForm: () => {
			return formRef.current as unknown as FormActionType;
		},
		setShowPagination: async (show: boolean) => {
			await getTableInstance()?.setShowPagination(show);
		},
		getShowPagination: () => {
			return getTableInstance()?.getShowPagination();
		},
		expandAll: () => {
			getTableInstance()?.expandAll();
		},
		expandRows: (keys: Key[]) => {
			getTableInstance()?.expandRows(keys);
		},
		collapseAll: () => {
			getTableInstance()?.collapseAll();
		},
		// scrollTo: (pos: string) => {
		// 	getTableInstance().scrollTo(pos);
		// },
		setShowForm: async (flag: boolean) => {
			await getTableInstance()?.setShowForm(flag);
		},
		getShowForm: () => {
			return getTableInstance()?.getShowForm();
		}
	};

	return [register, methods];
}
